package com.ddx.myopengles20.newpackage;

import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;

import com.ddx.myopengles20.R;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;


/**
 * 开奖动画
 * Created by aaa on 2017/4/5.
 */

public class AllGLRender implements GLSurfaceView.Renderer {

    private GLSurfaceView mGLSurfaceView;
    private Context mContext;
    private String mVertexShader; //顶点着色器
    private String mFragmentShader; //片元着色器
    private int mProgram; //自定义渲染管线程序id
    private int mVertexLocation; //顶点位置属性引用id
    private int mTextureLocation; //纹理位置属性引用id
    private int mMvpUniform; //总变换矩阵引用id
    private FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
    private FloatBuffer mTextureBuffer;//纹理坐标数据缓冲
    private float mRatio = 1.0f;//坐标宽高比
    private final int mMaxTexture = 220;//产生的纹理id的数量
    private int[] mTextureID;//纹理id的数组
    private int colorHandle;//片画笔
    private int hIsHalf;



    private Bitmap mBitmap_Compass_Direct;//背景
    private Bitmap mBitmap_Compass;//摇奖机
    private Bitmap mBitmap_Line;//摇奖机


    private final float STANDARD_COOED = 1.0f;//整个界面坐标
    private final float ZORE_COOED = 0.0f;//整个界面坐标
    private final float ZORE_COOED_1 = -0.1f;//整个界面坐标

    //指南针左右上下的值
    private final float COMPASS_COOED_X = 0.22f;//指南针左右坐标
    private final float COMPASS_COOED_Y = 0.225f;//指南针上面的坐标
    //向下平移多少
    private final float COMPASS_COOED_TRANSLATE = -0.75f;//指南针上面的坐标


    private final float COMPASS_DIRECT_COOED_X = 0.08f;//指南针左右坐标
    private final float COMPASS_DIRECT_COOED_Y = 0.225f;//指南针上面的坐标
    private final float COMPASS_DIRECT_TRANSLATE = -0.6f;//指南针上面的坐标

    private final float LINE_TRANSLATE_Y = -0.72f;//指南针上面的坐标
    private final float LINE_TRANSLATE_X = -0.05f;//指南针上面的坐标



    //直线
    private float[] stakeoutPoint;
    private float[] LINE_COOED_LEFT_END;

    //    围绕X轴旋转的角度
    public static float xrotate = 0f;
    //    围绕Y轴旋转的角度
    public static float yrotate = 0f;
    //    围绕Z轴旋转的角度
    public static float zrotate = 0f;


    //根据顶点获取长方形下面那个坐标的顶点
    private double[] getLineEndPoint(double[] point,double width,double angle){
        double[] line_cooed_left_point=new double[2];
        line_cooed_left_point[0]=point[0]+width*Math.sin(angle);
        line_cooed_left_point[1]=point[1]-width*Math.cos(angle);
        return line_cooed_left_point;
    }


    //计算两个点之间的角度
    private double getAngleByTwoPoint(double[] startPoint,double[] endPoint){
        return Math.atan2((endPoint[1]-startPoint[1]),(endPoint[0]-startPoint[0]));
    }


    public AllGLRender(GLSurfaceView glSurfaceView, Context context) {
        mGLSurfaceView = glSurfaceView;
        mContext = context;
        initData();

    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        //初始化着色器
        initShader();
        //设置屏幕背景色RGBA
        //注释掉表示全透明
        //GLES20.glClearColor(0, 1.0f, 1.0f, 1f);//清屏 设置背景色
        GLES20.glDisable(GLES20.GL_DEPTH_TEST);//关闭深度检测
        //开启混合
        GLES20.glEnable(GLES20.GL_BLEND);

        //png图片不用预乘alpha,混淆因子
        //GL_ONE：      表示使用1.0作为因子，实际上相当于完全的使用了这种颜色参与混合运算。
        //GL_ONE_MINUS_SRC_ALPHA：表示用1.0减去源颜色的alpha值来作为因子。
        //GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
        //关闭背面剪裁
        GLES20.glDisable(GLES20.GL_CULL_FACE);


        //初始化纹理ID
        initTexture(mBitmap_Compass, 0);
        initTexture(mBitmap_Compass_Direct, 1);
        initTexture(mBitmap_Line, 2);
    }

    double WIDTH=0.15f;
    double[] linePoint=new double[]{-0.1f,0f,0.1f,0f,-0.1f,1f,0.1f,1f};
    double[] linestartPoint ={0f,0.3f};
    double[] lineendPoint ={0f,-0.3f};
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        //设置视窗大小及位置
        GLES20.glViewport(0, 0, width, height);
        //计算GLSurfaceView的宽高比
        mRatio = (float) width / height;

        double angleByTwoPoint = getAngleByTwoPoint(linestartPoint, lineendPoint);
        double[] startPoint_right = getLineEndPoint(linestartPoint, WIDTH, angleByTwoPoint);
//        linePoint[0]= linestartPoint[0];
//        linePoint[1]= linestartPoint[1];
//        linePoint[2]=startPoint_right[0];
//        linePoint[3]=startPoint_right[1];
//
//
//        double[] endPoint_right = getLineEndPoint(lineendPoint, WIDTH, angleByTwoPoint);
//        linePoint[4]= lineendPoint[0];
//        linePoint[5]= lineendPoint[1];
//        linePoint[6]=endPoint_right[0];
//        linePoint[7]=endPoint_right[1];

        //初始化顶点及片元坐标
        initVertexData();
//        //调用此方法计算产生正交投影矩阵
        MatrixState.setProjectOrtho(-mRatio, mRatio, -1, 1, 2, 10);
        //调用此方法产生摄像机9参数位置矩阵
        MatrixState.setCamera(0, 0, 3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        //清除深度缓冲与颜色缓冲
        GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);

        drawLine();
        drawCompass();
        drawCompassDirect();
    }

    /**
     * 初始化数据
     */
    private void initData() {
        mTextureID = new int[mMaxTexture];
        //初始化图片
        mBitmap_Compass = BitmapUtils.readBitmap(mContext, R.mipmap.compass);
        mBitmap_Compass_Direct = BitmapUtils.readBitmap(mContext, R.mipmap.compass_direct);
        mBitmap_Line = BitmapUtils.readBitmap(mContext, R.mipmap.line);
    }

    /**
     * 初始化顶点数据
     */
    private void initVertexData() {
        float vertexArray[] = {   //顶点坐标
                //指南针
                -COMPASS_COOED_X, -COMPASS_COOED_Y, ZORE_COOED,    //左下角
                COMPASS_COOED_X, -COMPASS_COOED_Y, ZORE_COOED,     //右下角
                -COMPASS_COOED_X, COMPASS_COOED_Y, ZORE_COOED,    //左上角
                COMPASS_COOED_X, COMPASS_COOED_Y, ZORE_COOED,     //右上角

                //指南针方向
                -COMPASS_DIRECT_COOED_X, -COMPASS_DIRECT_COOED_Y, ZORE_COOED,    //左下角
                COMPASS_DIRECT_COOED_X, -COMPASS_DIRECT_COOED_Y, ZORE_COOED,     //右下角
                -COMPASS_DIRECT_COOED_X, COMPASS_DIRECT_COOED_Y, ZORE_COOED,    //左上角
                COMPASS_DIRECT_COOED_X, COMPASS_DIRECT_COOED_Y, ZORE_COOED,     //右上角
//
//
                (float) linePoint[0], (float)linePoint[1], ZORE_COOED,    //左下角
                (float) linePoint[2], (float)linePoint[3], ZORE_COOED,    //左下角
                (float) linePoint[4], (float) linePoint[5], ZORE_COOED,    //左下角
                (float) linePoint[6], (float) linePoint[7], ZORE_COOED,    //左下角


        };
        float textureArray[] = {   //纹理坐标
                ZORE_COOED, STANDARD_COOED,
                STANDARD_COOED, STANDARD_COOED,
                ZORE_COOED, ZORE_COOED,
                STANDARD_COOED, ZORE_COOED,

                ZORE_COOED, STANDARD_COOED,
                STANDARD_COOED, STANDARD_COOED,
                ZORE_COOED, ZORE_COOED,
                STANDARD_COOED, ZORE_COOED,

                ZORE_COOED, STANDARD_COOED,
                STANDARD_COOED, STANDARD_COOED,
                ZORE_COOED, ZORE_COOED,
                STANDARD_COOED, ZORE_COOED,


        };

        //创建顶点坐标数据缓冲
        //vertexArray.length*4是因为一个整数四个字节
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertexArray.length * 4);
        byteBuffer.order(ByteOrder.nativeOrder());//设置字节顺序
        mVertexBuffer = byteBuffer.asFloatBuffer();//转换为Float型缓冲
        mVertexBuffer.put(vertexArray);//向缓冲区中放入顶点坐标数据
        mVertexBuffer.position(0);//设置缓冲区起始位置
        byteBuffer.clear();

        //创建纹理坐标数据缓冲
        //textureArray.length*4是因为一个整数四个字节
        ByteBuffer byteBuffer2 = ByteBuffer.allocateDirect(textureArray.length * 4);
        byteBuffer2.order(ByteOrder.nativeOrder());//设置字节顺序
        mTextureBuffer = byteBuffer2.asFloatBuffer();//转换为Float型缓冲
        mTextureBuffer.put(textureArray);//向缓冲区中放入纹理坐标数据
        mTextureBuffer.position(0);//设置缓冲区起始位置
        byteBuffer2.clear();

        //为画笔指定顶点位置数据，将顶点坐标位置传递进渲染管线，以便管线经过基本处理后将对应的值传递给顶点着色器中的属性（attribute）变量
        GLES20.glVertexAttribPointer
                (
                        mVertexLocation, //顶点位置属性引用
                        3,               //每个顶点的数据个数（这是是x,y,z坐标，所以为3）
                        GLES20.GL_FLOAT, //数据类型
                        false,           //是否格式化
                        3 * 4,           //每个数据的尺寸，这里每组3个浮点数组(X,Y,Z轴坐标)，每个浮点数4个字节，共3*4个字节
                        mVertexBuffer    //存放了数据的缓存
                );
        //为画笔指定顶点纹理坐标数据，将纹理坐标位置传递进渲染管线，，以便管线经过基本处理后将对应的值传递给顶点着色器中的属性（attribute）变量
        GLES20.glVertexAttribPointer
                (
                        mTextureLocation,  //纹理位置属性引用
                        2,                 //每个顶点的数据个数（这是是x,y坐标，所以为2）
                        GLES20.GL_FLOAT,   //数据类型
                        false,             //是否格式化
                        2 * 4,             //每个数据的尺寸，这里每组2个浮点数组(X,Y轴坐标)，每个浮点数4个字节，共2*4个字节
                        mTextureBuffer     //存放了数据的缓存
                );

        //允许用到的属性数据数组
        GLES20.glEnableVertexAttribArray(mVertexLocation);//启用顶点位置数据
        GLES20.glEnableVertexAttribArray(mTextureLocation);//启用纹理位置坐标数据
    }

    /**
     * 初始化着色器
     */
    private void initShader() {
        //加载顶点着色器的脚本内容
        mVertexShader = ShaderUtil.loadFromAssetsFile("vertex.sh", mGLSurfaceView.getResources());
        //加载片元着色器的脚本内容
        mFragmentShader = ShaderUtil.loadFromAssetsFile("fragment.sh", mGLSurfaceView.getResources());
        //基于顶点着色器与片元着色器创建程序
        mProgram = ShaderUtil.createProgram(mVertexShader, mFragmentShader);
        //获取mProgram程序中顶点位置属性引用id
        mVertexLocation = GLES20.glGetAttribLocation(mProgram, "vertexPosition");
        //获取mProgram程序中纹理位置属性引用id
        mTextureLocation = GLES20.glGetAttribLocation(mProgram, "textureCoor");
        //获取程序中总变换矩阵引用id
        mMvpUniform = GLES20.glGetUniformLocation(mProgram, "mvpMatrix");
        colorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
        hIsHalf=GLES20.glGetUniformLocation(mProgram,"vIsHalf");


    }

    /**
     * 初始化纹理,根据ID获取对应的纹理背景glBindTexture
     */
    private void initTexture(Bitmap bitmap, int ID) {
        //生成纹理ID
        int[] textures = new int[1];
        GLES20.glGenTextures(1,     //产生的纹理id的数量
                textures,   //纹理id的数组
                0             //偏移量
        );
        mTextureID[ID] = textures[0];
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID[ID]);//绑定对应的textureID
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);//设置mix时为线性采样
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);//设置MAG时为线性采样
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);//设置S轴的拉伸方式为截取
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);//设置T轴的拉伸方式为截取
//        Log.v("data", "此时的bitmap_Background==" + bitmap);
        //实际加载纹理进显存
        GLUtils.texImage2D
                (
                        GLES20.GL_TEXTURE_2D,   //纹理类型，在OpenGL ES中必须为GL10.GL_TEXTURE_2D
                        0,                      //纹理的层次，0表示基本图像层，可以理解为直接贴图
                        bitmap,                 //纹理图像
                        0                       //纹理边框尺寸
                );
        bitmap.recycle();          //纹理加载成功后释放图片
    }


    /**
     * 画背景
     */
    private void drawCompass() {
        //制定使用某套shader程序
        GLES20.glUseProgram(mProgram);
        //获取不变换初始矩阵
        MatrixState.setInitStack();
        //先原点画，然后在平移到自己的地方，然后在旋转
        MatrixState.translate(0,COMPASS_COOED_TRANSLATE,0);
        MatrixState.rotateM(xrotate,1,0,0);
        MatrixState.rotateM(zrotate,0,0,1);

        drawArrays(mMvpUniform, 0, 0, 4);
    }

    /**
     * 画摇奖机
     */
    private void drawCompassDirect() {
        GLES20.glUseProgram(mProgram);
        MatrixState.setInitStack();
        //先原点画，然后在平移到自己的地方，然后在旋转
        MatrixState.translate(0,COMPASS_DIRECT_TRANSLATE+(xrotate/950),0f);
        MatrixState.rotateM(xrotate,1,0,0);
        drawArrays(mMvpUniform, 1, 4, 4);
    }

    private void drawLine() {
        GLES20.glUseProgram(mProgram);

        MatrixState.setInitStack();
        //先原点画，然后在平移到自己的地方，然后在旋转
        MatrixState.translate(0f, LINE_TRANSLATE_Y,0);
        MatrixState.rotateM(zrotate-45,0,0,1);
        //MatrixState.scale(1,0.5f,1);

        drawArrays(mMvpUniform, 2, 8, 4);
    }



    /**
     * 绘制纹理
     */
    private void drawArrays(int location, int texture_id, int first, int count) {
//        GLES20.glUniform1i(hIsHalf,2);
        //将最终变换矩阵（一致性变量）传入渲染管线
        GLES20.glUniformMatrix4fv(location, 1, false, MatrixState.getFinalMatrix(), 0);
        //绑定纹理
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);//设置使用的纹理编号
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID[texture_id]);//绑定指定的纹理ID
        //绘制纹理矩形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, first, count);
    }


}
